﻿using System;
using Gumini.JulaDB.DataTypes;

namespace Gumini.JulaDB.Expressions.Operators
{
    internal abstract class LogicalOperator : BinaryOperator
    {
        public LogicalOperator(params string[] names)
            : base(names) { }

        protected abstract bool? EvaluateCore(bool? a, bool? b);

        public override TypedValue Evaluate(TypedValue left, TypedValue right)
        {
            var boolType = DataType.Bool;
            bool? a = (bool?)boolType.ConvertFrom(left.Value);
            bool? b = (bool?)boolType.ConvertFrom(right.Value);

            return new TypedValue(DataType.Bool, EvaluateCore(a, b));
        }

        public override DataType GetReturnType()
        {
            return DataType.Bool;
        }

        protected static int BoolToInteger(bool? source)
        {
            if (source == null)
                return 0;
            else if (source.Value)
                return 1;
            else
                return -1;
        }

        protected static bool? IntegerToBool(int source)
        {
            switch (source)
            {
                case -1:
                    return false;
                case 0:
                    return null;
                case 1:
                    return true;
                default:
                    throw new InvalidOperationException("Unexpected boolean representation");
            }
        }
    }
}
